// 控制器基类

package web

import (
	"api/common"
	"api/common/logger"
	"encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

//JSON输出
func ServeJSON(w http.ResponseWriter, JsonData interface{}) {
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	if jsondata, err := json.Marshal(JsonData); err == nil {
		_, _ = fmt.Fprint(w, string(jsondata))
	} else {
		http.Error(w, "数据JSON编码错误", 500)
		logger.Error("数据JSON编码错误", err)
	}
}

//HTML输出
func ServeHtmlTpl(w http.ResponseWriter, tplName string, htmlData interface{}) {
	tpl := template.New(common.CurDir + common.Config.ViewsPath + "/" + tplName)
	_ = tpl.Execute(w, htmlData)
}

// 用户令牌检查
func TokenCheckRequest(request *http.Request) (map[string]interface{}, *JsonMsg) {
	result, _ := ioutil.ReadAll(request.Body)
	inputJson := map[string]interface{}{}
	err := json.Unmarshal(result, &inputJson)
	if err != nil {
		logger.Error("请求JSON无法解析", err)
		return nil, &JsonMsg{false, "请求JSON无法解析", 1}
	}

	userId := inputJson["userId"]
	token := inputJson["token"]

	if userId == nil {
		return nil, &JsonMsg{false, "用户id不能为空", 1}
	}
	if token == nil || token == "" {
		return nil, &JsonMsg{false, "访问令牌不能为空", 1}
	}

	key := fmt.Sprintf("app_user_%d", int64(userId.(float64)))
	url := request.URL.Path
	if !strings.HasPrefix(url, "/api") {
		key = fmt.Sprintf("admin_user_%d", int64(userId.(float64)))
	}

	tokenCache := ""
	err = common.RedisClient.Get(key).Scan(&tokenCache)
	if err != nil && common.ToStr(err) != "redis: nil" {
		logger.Error("在获取redis里的token时发生错误", err)
		return nil, &JsonMsg{false, "在获取redis里的token时发生错误", 1}
	}
	if common.ToStr(token) != tokenCache {
		return nil, &JsonMsg{false, "登录状态已失效，请重新登录！", 401}
	}

	if !strings.HasPrefix(url, "/api") {
		ttl, err := common.RedisClient.TTL(key).Result()
		if err != nil {
			logger.Error("获取访问令牌的有效时间(TTL)发生错误", err)
			return nil, &JsonMsg{false, "获取访问令牌的有效时间(TTL)发生错误", 401}
		}
		if ttl.Seconds() <= 1 {
			return nil, &JsonMsg{false, "登录状态已失效，请重新登录！", 401}
		}

		// 访问令牌的有效时长进行一次延长(续期)
		common.RedisClient.Expire(key, time.Minute*common.Config.AdminTokenValidMinute)
	}

	fmt.Println(time.Now().Format("2006-01-02 15:04:05"), url)
	fmt.Println(inputJson)
	return inputJson, nil
}

//用户令牌免检查
func ExemptTokenCheckRequest(request *http.Request) (map[string]interface{}, *JsonMsg) {
	result, _ := ioutil.ReadAll(request.Body)
	inputJson := map[string]interface{}{}
	if err := json.Unmarshal(result, &inputJson); err != nil {
		return nil, &JsonMsg{false, "请求JSON无法解析", 1}
	}

	return inputJson, nil
}
